<?php

namespace App\Services;

use Illuminate\Support\Facades\Log;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

/**
 * Copyright (C), 2021-2021, Shall Buy Life info. Co., Ltd.
 * FileName: ${FILE_NAME}
 * Description: 说明
 *
 * @author lwl
 * @Create Date    2021/11/8 11:04
 * @Update Date    2021/11/8 11:04 By lwl
 * @version v1.0
 */
class RmqClientService
{
    /**
     * @var object $instance 单例对象
     */
    private static $instance = null;

    /**
     * @var object $connection 队列连接对象
     */
    private $connection = null;

    /**
     * @var object $channel 队列通道对象
     */
    private $channel = null;

    /**
     * @var object $message 队列消息对象
     */
    private $message = null;

    /**
     * 构造函数
     *
     */
    private function __construct()
    {
        //dd(config('queue.connections.rabbitmq.vhost'));
        $this->connection = new AMQPStreamConnection(
            config('queue.connections.rabbitmq.host'),
            config('queue.connections.rabbitmq.port'),
            config('queue.connections.rabbitmq.login'),
            config('queue.connections.rabbitmq.password'),
            config('queue.connections.rabbitmq.vhost')
        );
        $this->channel = $this->connection->channel();
        $this->message = new AMQPMessage('', ['content_type' => 'json', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
    }

    /**
     * FunctionName：__clone
     * Description：克隆
     * Author：lwl
     */
    private function __clone()
    {}

    /**
     * 析构函数
     */
    public function __destruct()
    {
        $this->channel->close();
        $this->connection->close();
        self::$instance = null;
    }

    /**
     * FunctionName：getInstance
     * Description：单例实例化入口
     * Author：lwl
     * @return RmqClientService|object|null
     */
    public static function getInstance()
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * FunctionName：consumer
     * Description：消费队列
     * Author：lwl
     * @param string $queue 队列名称
     * @param boolean $bForceDelete 是否取后即删
     * @return AMQPMessage|null
     */
    public function consumer(string $queue, bool $bForceDelete = false)
    {
        try {
            // 取数据
            // 声明队列
            // 不检测同名队列，持久化，不允许其他队列访问，不自动删除队列
            $this->channel->queue_declare($queue, false, true, false, false);
            $message = $this->channel->basic_get($queue);
            if ($message && $bForceDelete) {
                // 回复确认信息
                $this->channel->basic_ack($message->delivery_info['delivery_tag']);
            }
        } catch (\Exception $exception) {
            Log::info($exception->getMessage());
        }
        return $message;
    }

    /**
     * FunctionName：ack
     * Description：
     * Author：lwl
     * @param $nTag 消息传递标签
     * @return mixed
     */
    public function ack($nTag)
    {
        try {
            $this->channel->basic_ack($nTag);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
        return null;//success 个人响应
    }
}
